package com.atguigu.tingshu.search.listener;

import com.atguigu.tingshu.search.service.impl.ItemServiceImpl;
import org.redisson.api.RBloomFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplicationRunListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

import javax.swing.*;
import java.time.Duration;
import java.util.List;

/**
 * <a href="https://www.shallowrecall.top/">Recall`Blog</a></br>
 * <a href="https://github.com/ShallowRecall">GitHub</a>
 *
 * @author Recall
 * @createTime 2025/03/26 19:20
 * 利用SpringBoot的监听机制完成对布隆分布式数据的同步
 **/
//不能使用@Component--扫描机制    spi机制--手动放 listener一定要用spi机制
public class BloomFilterListener implements SpringApplicationRunListener {


    Logger logger = LoggerFactory.getLogger(this.getClass());

    /**
     * 该方法SpringBoot在启动过程（就包含了spring容器中应用定义的Bean对象都创建完毕）中回调
     *
     * @param context
     * @param timeTaken started方法在容器启动的过程中调用两次。
     *                  第一次是springcloud的组件调用的。   ConfigurationApplicationContext spring容器里面是没有定义好的Bean对象
     *                  第一次是springboot的组件调用的。   ConfigurationApplicationContext spring容器里面才有定义好的Bean对象
     */
    @Override
    public void started(ConfigurableApplicationContext context, Duration timeTaken) {

        boolean containsBean = context.containsBean("rBloomFilter");

        if (!containsBean) {
            return;
        }

        // 1.从spring容器中获取到布隆过滤器的Bean对象
        RBloomFilter rBloomFilter = context.getBean("rBloomFilter", RBloomFilter.class);

        if (rBloomFilter.count() == 0) {
            // 2.从spring容器中获取应用的Bean对象
            ItemServiceImpl itemServiceImpl = context.getBean("itemServiceImpl", ItemServiceImpl.class);
            // 3.获取数据
            List<Long> albumInfoIdList = itemServiceImpl.getAlbumInfoIdList();
            // 4.将数据放到布隆过滤器中
            albumInfoIdList.stream().forEach(rBloomFilter::add);
            // 5.布隆过滤器元素是否同步进去
            logger.info("布隆过滤器初始化成功,且布隆中的元素个数为：{}", rBloomFilter.count());
        }

    }
}
